/*
 * Copyright 2010 Cedric Priscal
 *
 * This file is part of stupid-avr-robot.
 *
 * stupid-avr-robot is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * stupid-avr-robot is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with stupid-avr-robot.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef PROPERTY_H_
#define PROPERTY_H_

class Property;

#include "PropertyListener.h"

/**
 * @brief Property types.
 */
typedef enum {
	PROPERTY_TYPE_INVALID,	//!< The property type has not been received from remote device.
	PROPERTY_TYPE_UNKNOWN,	//!< The property type has not yet been defined.
	PROPERTY_TYPE_VOID,  	//!< The property has no value, but some children.
	PROPERTY_TYPE_BOOL,  	//!< The property holds a boolean value.
	PROPERTY_TYPE_U16,   	//!< The property holds an unsigned 16 bits integer.
	PROPERTY_TYPE_S16,   	//!< The property holds an unsigned 16 bits integer.
	PROPERTY_TYPE_S8        //!< The property holds a signed 8 bits integer.
} PROPERTY_TYPE;

/**
 * @brief Base abstract class for all properties.
 */
class Property {

private:

protected:
	/**
	 * @brief Constructor.
	 * @param listener A listener to be called when the property is modified.
	 */
	Property(PropertyListener* listener = 0);

	/**
	 * @brief A listener to be called when the property is modified.
	 */
	PropertyListener* mListener;

public:
	/**
	 * @brief Get the type of the property.
	 * @return Type of the property.
	 */
	virtual PROPERTY_TYPE getType();

	/**
	 * @brief Get the name of the property.
	 * @return Name of the property.
	 */
	virtual const char* getName() = 0;

	/**
	 * @brief Get the description of the property.
	 * @return Description of the property.
	 */
	virtual const char* getDescription() = 0;

	/**
	 * @brief Get the value of the property.
	 * @param[out] value Value of the property.
	 * @param[out] size Size in bytes of @a value.
	 * getValue() may return with @a value = NULL, and @a size = 0
	 * if this property has no value, or if its value is write only.
	 */
	virtual void getValue(const unsigned char* & value, char & size);

	/**
	 * @brief Set the value of the property.
	 * @param[in] value Pointer to the new value.
	 * @param[in] size Size in bytes of @a value.
	 * setValue() may ignore this call if this property is read only.
	 */
	virtual void setValue(const unsigned char* value, char size);

	/**
	 * @brief Get a child of this property.
	 * @param[in] index property index.
	 * @return A pointer to the child, or 0 if the index is out of bound.
	 */
	virtual Property* getChild(unsigned char index);
};

#endif /* PROPERTY_H_ */
